package middleware

import (
	"encoding/base64"
	"strings"

	"gitee.com/youkelike/ziam/zcode/zcode"
	"gitee.com/youkelike/ziam/zerrors"
	"gitee.com/youkelike/ziam/zutils/response"
	"github.com/gin-gonic/gin"
)

type BasicStrategy struct {
	compare func(username string, password string) bool
}

var _ AuthStrategy = &BasicStrategy{}

func NewBasicStrategy(compare func(username, password string) bool) BasicStrategy {
	return BasicStrategy{
		compare: compare,
	}
}

// 这里也可以不用闭包，直接把函数签名改成 func(c *gin.Context) 这种形式，同时 AuthStrategy 也要改它的接口方法签名，
// 只要结构体方法的签名和接口方法的签名一样，就可以赋值给接口变量
func (b BasicStrategy) AuthFunc() gin.HandlerFunc {
	return func(c *gin.Context) {
		auth := strings.SplitN(c.Request.Header.Get("Authorization"), " ", 2)
		if len(auth) != 2 || auth[0] != "Basic" {
			response.Write(c, zerrors.WithCode(zcode.ErrSignatureInvalid, "Authorization header format is wrong."), nil)
			c.Abort()
			return
		}

		payload, _ := base64.StdEncoding.DecodeString(auth[1])
		pair := strings.SplitN(string(payload), ":", 2)
		if len(pair) != 2 || !b.compare(pair[0], pair[1]) {
			response.Write(c, zerrors.WithCode(zcode.ErrSignatureInvalid, "Authorization header format is wrong."), nil)
			c.Abort()
			return
		}

		// 登陆成功设置全局标识
		c.Set(UsernameKey, pair[0])

		c.Next()
	}
}
